<?php


namespace app\api\controller;
use app\api\model\CouponLog;
use think\Request;
use think\exception\ValidateException;
use app\api\BaseController;
require_once '/www/wwwroot/stop/public/plugins/pay/addons/wechat/lib/WxPay.Api.php';
require_once '/www/wwwroot/stop/public/plugins/pay/addons/wechat/example/WxPay.NativePay.php';
require_once '/www/wwwroot/stop/public/plugins/pay/addons/wechat/example/WxPay.JsApiPay.php';
require_once '/www/wwwroot/stop/public/plugins/pay/addons/wechat/example/WxPay.Config.php';
class Order extends BaseController
{
    public $middleware = [\app\api\middleware\AuthCheck::class];

    public function index(){
        if ($this->request->isPost()) {
            $page=input("post.page");
            $page_size=input("post.page_size");
            $page=$page?$page:1;
            $page_size=$page_size?$page_size:15;
            if(empty( $this->request->userId )){
                return json(['status'=>'login', 'message'=> '请登录后操作！']);
            }
            $count =(new \app\admin\model\Order())->where('user_id', $this->request->userId)->count();
            $list =(new\app\admin\model\Order())->where('user_id', $this->request->userId)->page($page, $page_size)->order('id desc')->select()->toArray();
            $totalPages = ceil($count / $page_size);
            $data['list']=$list;
            $data['count']=$count;
            $data['totalPages']=$totalPages;
            return json(["status" => "success", "message" => "请求成功", "data" => $data]);
        }
    }

    public function initOrder(){
        $data=input("post.");
        try {
            validate(\app\api\validate\Order::class)->scene("init")->check($data);
        } catch ( ValidateException $e ) {
            return json(["status" => "error", "message" => $e->getError()]);
        }
        $stop=(new \app\admin\model\Stop())->where('id',$data['stop_id'])->findOrEmpty()->toArray();
        if(empty($stop)){
            return json(["status" => "error", "message" =>'请选择停车场']);
        }
        $amount=$stop['single_amount']*$data['day'];
        $coupon=(new CouponLog())->where('user_id', $this->request->userId)->where('status',1)->where('amount','>=',$amount)->where('start_time','<',date('Y-m-d H:i:s'))->where('end_time','>',date('Y-m-d H:i:s'))->select()->toArray();
        $discount=(new \app\admin\model\Discount())->where('user_id', $this->request->userId)->where('status',1)->where('amount','>=',$amount)->where('start_time','<',date('Y-m-d H:i:s'))->where('end_time','>',date('Y-m-d H:i:s'))->select()->toArray();
        return json(["status" => "success", "data" => ['coupon'=>$coupon?$coupon:[],'amount'=>$amount,'discount'=>$discount]]);
    }

    public function create(){
        $data=input("post.");
        try {
            validate(\app\api\validate\Order::class)->scene("create")->check($data);
        } catch ( ValidateException $e ) {
            return json(["status" => "error", "message" => $e->getError()]);
        }
        $stop=(new \app\admin\model\Stop())->where('id',$data['stop_id'])->findOrEmpty()->toArray();
        if(empty($stop)){
            return json(["status" => "error", "message" =>'请选择停车场']);
        }
        $carData=(new \app\admin\model\CarNumber())->where('id',$data['car_id'])->findOrEmpty()->toArray();
        if(empty($carData)){
            return json(["status" => "error", "message" =>'请选择车牌号']);
        }
        if($data['channel']==3){
            if(!isset($data['coupon_id']) || empty($data['coupon_id'])){
                return json(["status" => "error", "message" => '请选择优惠券']);
            }
            $amount=$stop['single_amount']*$data['day'];
            $coupon=(new CouponLog())->where('user_id', $this->request->userId)->where('id',$data['coupon_id'])->where('status',1)->where('amount','>=',$amount)->where('start_time','<',date('Y-m-d H:i:s'))->where('end_time','>',date('Y-m-d H:i:s'))->findOrEmpty()->toArray();
            if(empty($coupon)){
                return json(["status" => "error", "message" =>'兑换券不可用']);
            }
            $orderData['car_id']=$data['car_id'];
            $orderData['mobile']=$data['mobile'];
            $orderData['car_number']=$carData['car_number'];
            $orderData['car_name']=$carData['car_name'];
            $orderData['user_id']=$this->request->userId;
            $orderData['merchant_id']=$stop['merchant_id'];
            $orderData['stop_id']=$data['stop_id'];
            $orderData['channel']=$data['channel'];
            $orderData['create_time']=date('Y-m-d H:i:s');
            $orderData['total_amount']=$amount;
            $orderData['init_day']=$data['day'];
            $orderData['init_amount']=$amount;
            $orderData['init_pay_status']=1;
            $orderData['master_order_sn']='M'.date('YmdHis').rand(10000,99999);
            $orderData['init_create_time']=date('Y-m-d H:i:s');
            $orderData['init_pay_time']=date('Y-m-d H:i:s');
            $orderData['coupon_id']=$data['coupon_id'];
            $orderData['single_amount']=$stop['single_amount'];
            $order_id=(new \app\admin\model\Order())->insertGetId($orderData);
            (new CouponLog())->where('user_id', $this->request->userId)->where('id',$data['coupon_id'])->update(['status'=>2]);
            return json(["status" => "success", "data" =>['channel'=>$data['channel'],'pay_status'=>1,'order_id'=>$order_id]]);
        }else if($data['channel']==1){
            $amount=$stop['single_amount']*$data['day'];
            $orderData['car_id']=$data['car_id'];
            $orderData['mobile']=$data['mobile'];
            $orderData['car_number']=$carData['car_number'];
            $orderData['car_name']=$carData['car_name'];
            $orderData['user_id']=$this->request->userId;
            $orderData['merchant_id']=$stop['merchant_id'];
            $orderData['stop_id']=$data['stop_id'];
            $orderData['channel']=$data['channel'];
            $orderData['create_time']=date('Y-m-d H:i:s');
            $orderData['total_amount']=$amount;
            $orderData['init_day']=$data['day'];
            $orderData['init_pay_amount']=$amount;
            $orderData['init_amount']=$amount;
            $orderData['master_order_sn']='M'.date('YmdHis').rand(10000,99999);
            $orderData['start_order_sn']='S'.date('YmdHis').rand(10000,99999);
            $orderData['init_create_time']=date('Y-m-d H:i:s');
            $orderData['single_amount']=$stop['single_amount'];
            if(isset($data['discount_id']) && $data['discount_id']){
                $coupon=(new \app\admin\model\Discount())->where('user_id', $this->request->userId)->where('id',$data['discount_id'])->where('status',1)->where('cill_amount','>=',$amount)->where('start_time','<',date('Y-m-d H:i:s'))->where('end_time','>',date('Y-m-d H:i:s'))->findOrEmpty()->toArray();
                if(empty($coupon)){
                    return json(["status" => "error", "message" =>'兑换券不可用']);
                }
                (new  \app\admin\model\Discount())->where('user_id', $this->request->userId)->where('id',$data['discount_id'])->update(['status'=>2]);
                $orderData['init_pay_amount']=$orderData['total_amount']-$coupon['amount'];
                $orderData['discount_id']=$data['discount_id'];
            }
            $order_id=(new \app\admin\model\Order())->insertGetId($orderData);
            $openId=(new \app\api\model\User())->where('id',$this->request->userId)->value('openid');
            $notify='http://www.tftcc.cn'.'/api/notify/start_pay_call';
            $result=$this->jsPay($openId,$orderData['start_order_sn'], $orderData['init_pay_amount'],$notify);
            if($result['status']=='error'){
                return json($result);
            }else{
                return json(["status" => "success", "data" =>['channel'=>$data['channel'],'pay_status'=>0,'order_id'=>$order_id,'jsApiParameters'=>$result['data']['jsApiParameters']]]);
            }
        }
    }

    private  function jsPay($openId,$orderSn, $rmb,$notify)
    {
        $config = new \WxPayConfig();
        if (empty($config->config)) {
            return ['status' => 'error', 'message' => '未配置微信支付功能'];
        }
        if ($config->open() == 1) {
            //①、获取用户openid
            $tools = new \JsApiPay();
            //②、统一下单
            $input = new \WxPayUnifiedOrder();
            $input->SetBody('停车费用');
            $input->SetAttach('停车费用');
            $input->SetGoods_tag("a");
            $input->SetOut_trade_no($orderSn);
            $input->SetTotal_fee($rmb * 100);
            $input->SetTime_start(date("YmdHis"));
            $input->SetTime_expire(date("YmdHis", time() + 60*30));
            $input->SetNotify_url($notify);
            $input->SetTrade_type("JSAPI");
            $input->SetProduct_id("123456789");
            $input->SetOpenid($openId);
            $result = \WxPayApi::unifiedOrder($config, $input);
            if ($result['return_code'] == 'SUCCESS' && $result["result_code"] == "SUCCESS") {
                $result['jsApiParameters'] = $tools->GetJsApiParameters($result);
                return ['status' => 'success', 'message' => '生成成功', 'data' => $result];
            } else {
                return ['status' => 'error', 'message' => '生成失败', 'data' => []];
            }
        } else {
            return ['status' => 'error', 'message' => '系统暂时关闭微信支付'];
        }
    }
    public function fastPay(){
        $data=input("post.");
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        if($order['sign_type']!=0){
            return json(['status' => 'error', 'message' => '订单状态异常']);
        }
        if($order['channel']!=1){
            return json(['status' => 'error', 'message' => '订单状态异常']);
        }
        if($order['init_pay_status']!=0){
            return json(['status' => 'error', 'message' => '请勿重复支付']);
        }
        $orderData['start_order_sn']='S'.date('YmdHis').rand(10000,99999);
        $orderData['init_create_time']=date('Y-m-d H:i:s');
        $orderData['init_pay_status']=0;
        $openId=(new \app\api\model\User())->where('id',$this->request->userId)->value('openid');
        $notify='http://www.tftcc.cn'.'/api/notify/start_pay_call';
        $result=$this->jsPay($openId,$orderData['start_order_sn'], $orderData['init_pay_amount'],$notify);
        if($result['status']=='error'){
            return json($result);
        }else{
            (new \app\admin\model\Order())->where('id',$data['order_id'])->save($orderData);
            return json(["status" => "success", "data" =>['channel'=>$order['channel'],'pay_status'=>0,'order_id'=>$data['order_id'],'jsApiParameters'=>$result['data']['jsApiParameters']]]);
        }
    }

    public function delete(){
        $data=input("post.");
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        if(empty($order)){
            return json(['status' => 'error', 'message' => '订单已删除请勿重复操作']);
        }
        if($order['sign_type']!=0){
            return json(['status' => 'error', 'message' => '订单状态异常']);
        }
        if($order['channel']!=1){
            return json(['status' => 'error', 'message' => '订单状态异常']);
        }
        if($order['init_pay_status']==0 || $order['init_pay_status']==3){
            (new \app\admin\model\Order())->where('id',$data['order_id'])->delete();
            return json(['status' => 'success', 'message' => '操作成功']);
        }else{
            return json(['status' => 'error', 'message' => '订单状态异常']);
        }
    }

    public function detail(){
        $data=input("post.");
        if(!isset($data['order_id']) || empty($data['order_id'])){
            return json(["status" => "error", "message" =>'order_id缺失']);
        }
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        if($order['channel']==3){
            $order['coupon']=(new CouponLog())->where('id',$order['coupon_id'])->findOrEmpty()->toArray();
        }else{
            $order['coupon']=[];
        }
        $tools = new \JsApiPay();
        if($order['sign_type']==0){
            $type=1;
        }else{
            $type=2;
        }
        $order['sign_url']='http://www.tftcc.cn/'.$tools->getSignUrl($data['order_id'],'order',$type);
        return json(["status" => "success", "data" =>$order]);
    }
    public function orderSignDetail(){
        $data=input("post.");
        if(!isset($data['order_id']) || empty($data['order_id'])){
            return json(["status" => "error", "message" =>'order_id缺失']);
        }
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        $userData=(new \app\api\model\User())->where('id',$this->request->userId)->findOrEmpty()->toArray();
        $stopUser=(new \app\api\model\StopUser())->where('phone',$userData['mobile'])->where('merchant_id',$order['merchant_id'])->where('status',1)->findOrEmpty()->toArray();
        if(empty($stopUser)){
            return json(["status" => "success",'data'=>['permission'=>0,'order'=>[]], "message" =>'无核销权限']);
        }
        if($order['channel']==3){
            $order['coupon']=(new CouponLog())->where('id',$order['coupon_id'])->findOrEmpty()->toArray();
        }else{
            $order['coupon']=[];
        }
        if($order['sign_type']==1){
            if(date('h')<2){
                $now_date=date('Ymd',time()-3600*24);
            }else{
                $now_date=date('Ymd');
            }
            $start_time=date('Ymd',strtotime($order['init_pay_time']));
            $real_day=$now_date-$start_time<=0?1:$now_date-$start_time+1;
            if($order['init_day']==$real_day){
                $order['end_type']=1;
            }elseif ($order['init_day']>$real_day){
                $order['end_type']=3;
                $order['end_refund_amount']=round($order['single_amount']*($order['init_day']-$real_day),2);
            }elseif ($order['init_day']<$real_day){
                $order['end_type']=2;
                $order['end_pay_amount']=round($order['single_amount']*($real_day-$order['init_day']),2);
            }
            $order['real_day']=$real_day;
            $order['total_amount']=$real_day*$order['single_amount'];
        }
        return json(["status" => "success", "data" =>['permission'=>1,'order'=>$order]]);
    }

    public function orderSign(){
        $data=input("post.");
        if(!isset($data['order_id']) || empty($data['order_id'])){
            return json(["status" => "error", "message" =>'order_id缺失']);
        }
        if(!isset($data['type']) || empty($data['type'])){
            return json(["status" => "error", "message" =>'type缺失']);
        }
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        $userData=(new \app\api\model\User())->where('id',$this->request->userId)->findOrEmpty()->toArray();
        $stopUser=(new \app\api\model\StopUser())->where('phone',$userData['mobile'])->where('merchant_id',$order['merchant_id'])->where('status',1)->findOrEmpty()->toArray();
        if(empty($stopUser)){
            return json(["status" => "success",'data'=>['permission'=>0,'end_type'=>0,'refundResult'=>[]], "message" =>'无核销权限']);
        }
        if($data['type']==1){
            if($order['sign_type']>1){
                return json(["status" => "error", "message" =>'订单状态异常']);
            }
            if($order['sign_type']==1){
                return json(["status" => "error", "message" =>'请勿重复核销']);
            }
            (new \app\admin\model\Order())->where('id',$data['order_id'])->update(['sign_type'=>1,'start_time'=>date('Y-m-d H:i:s'),'start_user_id'=>$this->request->userId]);
            return json(["status" => "success", "data" =>[],'message'=>'操作成功']);
        }else{
            if($order['sign_type']!=1){
                return json(["status" => "error", "message" =>'订单状态异常']);
            }
            if(date('h')<2){
                $now_date=date('Ymd',time()-3600*24);
            }else{
                $now_date=date('Ymd');
            }
            $start_time=date('Ymd',strtotime($order['init_pay_time']));
            $real_day=$now_date-$start_time<=0?1:$now_date-$start_time+1;
            if($order['channel']==3){
                $saveData['end_type']=1;
                $saveData['sign_type']=3;
            }else{
                if($order['init_day']==$real_day){
                    $saveData['end_type']=1;
                    $saveData['sign_type']=3;
                }elseif ($order['init_day']>$real_day){
                    $saveData['end_type']=3;
                    $saveData['sign_type']=2;
                    $saveData['end_refund_amount']=round($order['single_amount']*($order['init_day']-$real_day),2);
                    if($order['discount_id']>0){
                        $amount=(new \app\admin\model\Discount())->where('id',$order['discount_id'])->value('amount');
                        if($amount>=$saveData['end_refund_amount']){
                            $saveData['end_type']=1;
                            $saveData['sign_type']=3;
                        }else{
                            $saveData['end_refund_amount']=$saveData['end_refund_amount']-$amount;
                        }
                    }
                }elseif ($order['init_day']<$real_day){
                    $saveData['end_type']=2;
                    $saveData['end_pay_amount']=round($order['single_amount']*($real_day-$order['init_day']),2);
                    $saveData['sign_type']=2;
                }
            }
            $saveData['real_day']=$real_day;
            $saveData['total_amount']=$real_day*$order['single_amount'];
            $saveData['end_time']=date('Y-m-d H:i:s');
            $saveData['end_user_id']=$this->request->userId;

            (new \app\admin\model\Order())->where('id',$data['order_id'])->update(['sign_type'=>1,'start_time'=>date('Y-m-d H:i:s'),'start_user_id'=>$this->request->userId]);
            if($saveData['end_type']==3){
                $saveData['refund_order_sn']='R'.date('YmdHis').rand(10000,99999);
                $saveData['refund_status']=2;
                $refundResult=$this->refund($order['start_order_sn'],$saveData['refund_order_sn'],$saveData['end_refund_amount'],$order['init_amount']);
                (new \app\admin\model\Order())->where('id',$data['order_id'])->update($saveData);
                return json(["status" => "success", "data" =>['permission'=>1,'end_type'=> $saveData['end_type'],'refundResult'=>$refundResult]]);
            }else{
                (new \app\admin\model\Order())->where('id',$data['order_id'])->update($saveData);
                return json(["status" => "success", "data" =>['permission'=>1,'end_type'=> $saveData['end_type'],'refundResult'=>[]]]);
            }
        }
    }

    private  function refund($orderId,$refund_order_sn, $rmb, $total, $reason = "")
    {
        $config = new \WxPayConfig();
        if (empty($config->config)) {
            return ['status' => 'error', 'message' => '未配置微信支付功能'];
        }
        if ($config->open() == 1) {
            $input = new \WxPayRefund();
            $input->SetOut_trade_no($orderId);
            $input->SetTotal_fee($total * 100);
            $input->SetRefund_fee($rmb * 100);
            $input->SetOut_refund_no($refund_order_sn);
            $input->SetOp_user_id($config->GetMerchantId());
            $input->SetNotify_url('http://www.tftcc.cn'.'/api/notify/refund_pay_call');
            $result = \WxPayApi::refund($config, $input);
            if ($result['return_code'] == 'SUCCESS' && $result["result_code"] == "SUCCESS") {
                return ['status' => 'success', 'message' => '退款成功', 'data' => $result];
            } else {
                return ['status' => 'error', 'message' => '退款失败', 'data' => $result];
            }
        } else {
            return ['status' => 'error', 'message' => '系统暂时关闭微信支付'];
        }
    }

    public function repay(){
        $data=input("post.");
        if(!isset($data['order_id']) || empty($data['order_id'])){
            return json(["status" => "error", "message" =>'order_id缺失']);
        }
        $order=(new \app\admin\model\Order())->where('id',$data['order_id'])->findOrEmpty()->toArray();
        if(empty($order)){
            return json(["status" => "error", "message" =>'参数异常']);
        }
        if($order['sign_type']!=2){
            return json(["status" => "error", "message" =>'订单状态异常']);
        }
        if($order['end_type']!=2){
            return json(["status" => "error", "message" =>'订单状态异常']);
        }
        if($order['again_pay_status']==1){
            return json(["status" => "error", "message" =>'请勿重复付款']);
        }
        $openId=(new \app\api\model\User())->where('id',$this->request->userId)->value('openid');
        $notify='http://www.tftcc.cn'.'/api/notify/end_pay_call';
        $saveData['end_order_sn']='E'.date('YmdHis').rand(10000,99999);
        $saveData['again_pay_status']=2;
        (new \app\admin\model\Order())->where('id',$data['order_id'])->update($saveData);
        $result=$this->jsPay($openId,$saveData['end_order_sn'],$order['end_pay_amount'],$notify);
        if($result['status']=='error'){
            return json($result);
        }else{
            return json(["status" => "success", "data" =>$result['data']['jsApiParameters']]);
        }
    }
}